Changes to make gdk-pixbuf threadsafe (#157310, #157306, Colin Walters):
authorMatthias Clasen <mclasen@redhat.com>
Fri, 12 Nov 2004 05:34:31 +0000 (05:34 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Fri, 12 Nov 2004 05:34:31 +0000 (05:34 +0000)
2004-11-12  Matthias Clasen  <mclasen@redhat.com>

Changes to make gdk-pixbuf threadsafe  (#157310, #157306,
Colin Walters):

* gdk-pixbuf-io.h (enum GdkPixbufFormatFlags): Add
GDK_PIXBUF_FORMAT_THREADSAFE to indicate that an image loader
is threadsafe.

* gdk-pixbuf-io.c (get_file_formats, _gdk_pixbuf_load_module):
Use a lock to make initialization of global data structures
threadsafe.
* gdk-pixbuf-private.h:
* gdk-pixbuf-io.c (_gdk_pixbuf_lock, _gdk_pixbuf_unlock):
Auxiliary functions which use another lock to protect
threadunsafe image loaders.

* gdk-pixbuf-io.c (gdk_pixbuf_real_save):
(save_to_callback_with_tmp_file):
(gdk_pixbuf_real_save_to_callback):
(gdk_pixbuf_new_from_xpm_data):
(_gdk_pixbuf_generic_image_load):
* gdk-pixbuf-animation.c (gdk_pixbuf_animation_new_from_file):
* gdk-pixbuf-loader.c (gdk_pixbuf_loader_load_module):
(gdk_pixbuf_loader_close):
(gdk_pixbuf_loader_finalize):
Use _gdk_pixbuf_lock() and _gdk_pixbuf_unlock().

* io-ani.c, io-bmp.c, io-gif.c, io-ico.c:
* io-jpeg.c, io-pcx.c, io-png.c, io-pnm.c:
* io-ras.c, io-tga.c, io-wbmp.c, io-xbm.c:
* io-xpm.c: Mark as threadsafe.

* io-tiff.c: Remove pointless locking, mark as
threadunsafe.

22 files changed:
docs/reference/ChangeLog
docs/reference/gdk-pixbuf/tmpl/module_interface.sgml
gdk-pixbuf/ChangeLog
gdk-pixbuf/gdk-pixbuf-animation.c
gdk-pixbuf/gdk-pixbuf-io.c
gdk-pixbuf/gdk-pixbuf-io.h
gdk-pixbuf/gdk-pixbuf-loader.c
gdk-pixbuf/gdk-pixbuf-private.h
gdk-pixbuf/io-ani.c
gdk-pixbuf/io-bmp.c
gdk-pixbuf/io-gif.c
gdk-pixbuf/io-ico.c
gdk-pixbuf/io-jpeg.c
gdk-pixbuf/io-pcx.c
gdk-pixbuf/io-png.c
gdk-pixbuf/io-pnm.c
gdk-pixbuf/io-ras.c
gdk-pixbuf/io-tga.c
gdk-pixbuf/io-tiff.c
gdk-pixbuf/io-wbmp.c
gdk-pixbuf/io-xbm.c
gdk-pixbuf/io-xpm.c

index 4916e93e718db537fb330d9d762c92454e9e6067..31be71caceedf3a732e0e926ca7f8f96616df817 100644 (file)
@@ -1,3 +1,8 @@
+2004-11-12  Matthias Clasen  <mclasen@redhat.com>
+
+       * gdk-pixbuf/tmpl/module_interface.sgml: Document 
+       GDK_PIXBUF_FORMAT_THREADSAFE.
+
 2004-11-09  Matthias Clasen  <mclasen@redhat.com>
 
        * gtk/gtk-sections.txt: Add gtk_action_get_accel_path.
index cca46f9bcf7ea1412879c89c75df8ec12e996f30..cfc176e318683e12369b010e228702bda6b5c432 100644 (file)
@@ -193,6 +193,9 @@ operations.
 
 @GDK_PIXBUF_FORMAT_WRITABLE: the module can write out images in the format.
 @GDK_PIXBUF_FORMAT_SCALABLE: the image format is scalable
+@GDK_PIXBUF_FORMAT_THREADSAFE: the module is threadsafe. If this flag is not
+  set, &gdk-pixbuf; will use a lock to prevent multiple threads from using
+  this module at the same time. (Since 2.6)
 @Since: 2.2
 
 <!-- ##### STRUCT GdkPixbufModulePattern ##### -->
index 44d768f5eb15c7cc37b03ec103280f0ec9fac861..e4bfddb8022f53c32aceb04685281df606b3d299 100644 (file)
@@ -1,3 +1,39 @@
+2004-11-12  Matthias Clasen  <mclasen@redhat.com>
+
+       Changes to make gdk-pixbuf threadsafe  (#157310, #157306, 
+       Colin Walters):
+       
+       * gdk-pixbuf-io.h (enum GdkPixbufFormatFlags): Add 
+       GDK_PIXBUF_FORMAT_THREADSAFE to indicate that an image loader
+       is threadsafe.
+
+       * gdk-pixbuf-io.c (get_file_formats, _gdk_pixbuf_load_module): 
+       Use a lock to make initialization of global data structures 
+       threadsafe.
+       * gdk-pixbuf-private.h: 
+       * gdk-pixbuf-io.c (_gdk_pixbuf_lock, _gdk_pixbuf_unlock): 
+       Auxiliary functions which use another lock to protect 
+       threadunsafe image loaders.
+       
+       * gdk-pixbuf-io.c (gdk_pixbuf_real_save): 
+       (save_to_callback_with_tmp_file): 
+       (gdk_pixbuf_real_save_to_callback): 
+       (gdk_pixbuf_new_from_xpm_data): 
+       (_gdk_pixbuf_generic_image_load): 
+       * gdk-pixbuf-animation.c (gdk_pixbuf_animation_new_from_file): 
+       * gdk-pixbuf-loader.c (gdk_pixbuf_loader_load_module): 
+       (gdk_pixbuf_loader_close): 
+       (gdk_pixbuf_loader_finalize): 
+       Use _gdk_pixbuf_lock() and _gdk_pixbuf_unlock().
+
+       * io-ani.c, io-bmp.c, io-gif.c, io-ico.c:
+       * io-jpeg.c, io-pcx.c, io-png.c, io-pnm.c:
+       * io-ras.c, io-tga.c, io-wbmp.c, io-xbm.c:
+       * io-xpm.c: Mark as threadsafe.
+       
+       * io-tiff.c: Remove pointless locking, mark as 
+       threadunsafe.
+
 2004-11-10  Matthias Clasen  <mclasen@redhat.com>
 
        * gdk-pixbuf-animation.c: 
index 5ea1ef6ee6930fb20326d75c63977886d2d84e80..fa6968c153f75f08a7bf13c8a6171a3b6e03189a 100644 (file)
@@ -181,6 +181,8 @@ gdk_pixbuf_animation_new_from_file (const char *filename,
                         return NULL;
                 }
 
+        _gdk_pixbuf_lock (image_module);
+
        if (image_module->load_animation == NULL) {
                GdkPixbuf *pixbuf;
 
@@ -208,7 +210,8 @@ gdk_pixbuf_animation_new_from_file (const char *filename,
                 
                if (pixbuf == NULL) {
                         g_free (display_name);
-                        return NULL;
+                        animation = NULL;
+                        goto out_unlock;
                 }
 
                 animation = gdk_pixbuf_non_anim_new (pixbuf);
@@ -241,6 +244,8 @@ gdk_pixbuf_animation_new_from_file (const char *filename,
 
         g_free (display_name);
 
+ out_unlock:
+        _gdk_pixbuf_unlock (image_module);
        return animation;
 }
 
index 7e12ee6e167a92de299a873b18fd8be4bd7e8791..9ad408748e5c55c650317ccac99571cbad8d9f17 100644 (file)
@@ -76,6 +76,25 @@ format_check (GdkPixbufModule *module, guchar *buffer, int size)
        return 0;
 }
 
+G_LOCK_DEFINE_STATIC (init_lock);
+G_LOCK_DEFINE_STATIC (threadunsafe_loader_lock);
+
+void
+_gdk_pixbuf_lock (GdkPixbufModule *image_module)
+{
+       if (!(image_module->info->flags & GDK_PIXBUF_FORMAT_THREADSAFE)) {
+               G_LOCK (threadunsafe_loader_lock);
+       }
+}
+void
+_gdk_pixbuf_unlock (GdkPixbufModule *image_module)
+{
+       if (!(image_module->info->flags & GDK_PIXBUF_FORMAT_THREADSAFE)) {
+               G_UNLOCK (threadunsafe_loader_lock);
+       }
+}
+
 static GSList *file_formats = NULL;
 
 static void gdk_pixbuf_io_init ();
@@ -83,8 +102,10 @@ static void gdk_pixbuf_io_init ();
 static GSList *
 get_file_formats (void)
 {
+       G_LOCK (init_lock);
        if (file_formats == NULL)
                gdk_pixbuf_io_init ();
+       G_UNLOCK (init_lock);
        
        return file_formats;
 }
@@ -396,9 +417,9 @@ gdk_pixbuf_io_init (void)
 /* actually load the image handler - gdk_pixbuf_get_module only get a */
 /* reference to the module to load, it doesn't actually load it       */
 /* perhaps these actions should be combined in one function           */
-gboolean
-_gdk_pixbuf_load_module (GdkPixbufModule *image_module,
-                         GError         **error)
+static gboolean
+_gdk_pixbuf_load_module_unlocked (GdkPixbufModule *image_module,
+                                 GError         **error)
 {
        char *path;
        GModule *module;
@@ -433,6 +454,19 @@ _gdk_pixbuf_load_module (GdkPixbufModule *image_module,
                 return FALSE;
         }
 }
+
+gboolean
+_gdk_pixbuf_load_module (GdkPixbufModule *image_module,
+                        GError         **error)
+{
+       gboolean ret;
+
+       G_LOCK (init_lock);
+       ret = _gdk_pixbuf_load_module_unlocked (image_module, error);
+       G_UNLOCK (init_lock);
+
+       return ret;
+}
 #else
 
 #define module(type) \
@@ -593,11 +627,11 @@ gdk_pixbuf_io_init ()
        };
        gchar **name;
        GdkPixbufModule *module = NULL;
-       
+
        for (name = included_formats; *name; name++) {
                module = g_new0 (GdkPixbufModule, 1);
                module->module_name = *name;
-               if (_gdk_pixbuf_load_module (module, NULL))
+               if (_gdk_pixbuf_load_module_unlocked (module, NULL))
                        file_formats = g_slist_prepend (file_formats, module);
                else
                        g_free (module);
@@ -703,37 +737,37 @@ _gdk_pixbuf_generic_image_load (GdkPixbufModule *module,
        GdkPixbufAnimation *animation = NULL;
        gpointer context;
 
-       if (module->load != NULL)
-               return (* module->load) (f, error);
-       
-       if (module->begin_load != NULL) {
+       _gdk_pixbuf_lock (module);
+
+       if (module->load != NULL) {
+               pixbuf = (* module->load) (f, error);
+       } else if (module->begin_load != NULL) {
                
                context = module->begin_load (NULL, prepared_notify, NULL, &pixbuf, error);
        
                if (!context)
-                       return NULL;
+                       goto out;
                
                while (!feof (f) && !ferror (f)) {
                        length = fread (buffer, 1, sizeof (buffer), f);
                        if (length > 0)
                                if (!module->load_increment (context, buffer, length, error)) {
                                        module->stop_load (context, NULL);
-                                       if (pixbuf != NULL)
+                                       if (pixbuf != NULL) {
                                                g_object_unref (pixbuf);
-                                       return NULL;
+                                               pixbuf = NULL;
+                                       }
+                                       goto out;
                                }
                }
                
                if (!module->stop_load (context, error)) {
-                       if (pixbuf != NULL)
+                       if (pixbuf != NULL) {
                                g_object_unref (pixbuf);
-                       return NULL;
+                               pixbuf = NULL;
+                       }
                }
-               
-               return pixbuf;
-       }
-       
-       if (module->load_animation != NULL) {
+       } else if (module->load_animation != NULL) {
                animation = (* module->load_animation) (f, error);
                if (animation != NULL) {
                        pixbuf = gdk_pixbuf_animation_get_static_image (animation);
@@ -741,12 +775,12 @@ _gdk_pixbuf_generic_image_load (GdkPixbufModule *module,
                        g_object_ref (pixbuf);
 
                        g_object_unref (animation);
-                       
-                       return pixbuf;
                }
        }
 
-       return NULL;
+ out:
+       _gdk_pixbuf_unlock (module);
+       return pixbuf;
 }
 
 /**
@@ -1134,14 +1168,18 @@ gdk_pixbuf_new_from_xpm_data (const char **data)
                         return NULL;
                 }
         }
-          
+
+       _gdk_pixbuf_lock (xpm_module);
+
        if (xpm_module->load_xpm_data == NULL) {
                g_warning ("gdk-pixbuf XPM module lacks XPM data capability");
-               return NULL;
-       } else
+               pixbuf = NULL;
+       } else {
                load_xpm_data = xpm_module->load_xpm_data;
+               pixbuf = (* load_xpm_data) (data);
+       }
 
-       pixbuf = (* load_xpm_data) (data);
+       _gdk_pixbuf_unlock (xpm_module);
        return pixbuf;
 }
 
@@ -1210,39 +1248,43 @@ gdk_pixbuf_real_save (GdkPixbuf     *pixbuf,
                       gchar        **values,
                       GError       **error)
 {
-       GdkPixbufModule *image_module = NULL;       
+       gboolean ret;
+       GdkPixbufModule *image_module = NULL;       
 
-       image_module = _gdk_pixbuf_get_named_module (type, error);
+       image_module = _gdk_pixbuf_get_named_module (type, error);
 
-       if (image_module == NULL)
-               return FALSE;
+       if (image_module == NULL)
+               return FALSE;
        
-       if (image_module->module == NULL)
-               if (!_gdk_pixbuf_load_module (image_module, error))
-                       return FALSE;
+       if (image_module->module == NULL)
+               if (!_gdk_pixbuf_load_module (image_module, error))
+                       return FALSE;
 
-       if (image_module->save) {
-              /* save normally */
-              return (* image_module->save) (filehandle, pixbuf,
+       _gdk_pixbuf_lock (image_module);
+
+       if (image_module->save) {
+               /* save normally */
+               ret = (* image_module->save) (filehandle, pixbuf,
                                              keys, values,
                                              error);
-       }
-       else if (image_module->save_to_callback) {
-              /* save with simple callback */
-              return (* image_module->save_to_callback) (save_to_file_callback,
+       } else if (image_module->save_to_callback) {
+               /* save with simple callback */
+               ret = (* image_module->save_to_callback) (save_to_file_callback,
                                                          filehandle, pixbuf,
                                                          keys, values,
                                                          error);
-       }
-       else {
-              /* can't save */
-               g_set_error (error,
-                            GDK_PIXBUF_ERROR,
-                            GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION,
-                            _("This build of gdk-pixbuf does not support saving the image format: %s"),
-                            type);
-               return FALSE;
-       }
+       } else {
+               /* can't save */
+               g_set_error (error,
+                            GDK_PIXBUF_ERROR,
+                            GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION,
+                            _("This build of gdk-pixbuf does not support saving the image format: %s"),
+                            type);
+               ret = FALSE;
+       }
+
+       _gdk_pixbuf_unlock (image_module);
+       return ret;
 }
 
 #define TMP_FILE_BUF_SIZE 4096
@@ -1283,8 +1325,13 @@ save_to_callback_with_tmp_file (GdkPixbufModule   *image_module,
                             _("Failed to open temporary file"));
                goto end;
        }
-       if (!(* image_module->save) (f, pixbuf, keys, values, error))
+
+       _gdk_pixbuf_lock (image_module);
+       retval = (image_module->save) (f, pixbuf, keys, values, error);
+       _gdk_pixbuf_unlock (image_module);
+       if (!retval)
                goto end;
+
        rewind (f);
        for (;;) {
                n = fread (buf, 1, TMP_FILE_BUF_SIZE, f);
@@ -1326,39 +1373,43 @@ gdk_pixbuf_real_save_to_callback (GdkPixbuf         *pixbuf,
                                  gchar            **values,
                                  GError           **error)
 {
-       GdkPixbufModule *image_module = NULL;       
+       gboolean ret;
+       GdkPixbufModule *image_module = NULL;       
 
-       image_module = _gdk_pixbuf_get_named_module (type, error);
+       image_module = _gdk_pixbuf_get_named_module (type, error);
 
-       if (image_module == NULL)
-               return FALSE;
+       if (image_module == NULL)
+               return FALSE;
        
-       if (image_module->module == NULL)
-               if (!_gdk_pixbuf_load_module (image_module, error))
-                       return FALSE;
+       if (image_module->module == NULL)
+               if (!_gdk_pixbuf_load_module (image_module, error))
+                       return FALSE;
+
+       _gdk_pixbuf_lock (image_module);
 
-       if (image_module->save_to_callback) {
-              /* save normally */
-              return (* image_module->save_to_callback) (save_func, user_data, 
+       if (image_module->save_to_callback) {
+               /* save normally */
+               ret = (* image_module->save_to_callback) (save_func, user_data, 
                                                          pixbuf, keys, values,
                                                          error);
-       }
-       else if (image_module->save) {
-              /* use a temporary file */
-              return save_to_callback_with_tmp_file (image_module, pixbuf,
+       } else if (image_module->save) {
+               /* use a temporary file */
+               ret = save_to_callback_with_tmp_file (image_module, pixbuf,
                                                      save_func, user_data, 
                                                      keys, values,
                                                      error);
-       }
-       else {
-              /* can't save */
-               g_set_error (error,
-                            GDK_PIXBUF_ERROR,
-                            GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION,
-                            _("This build of gdk-pixbuf does not support saving the image format: %s"),
-                            type);
-               return FALSE;
-       }
+       } else {
+               /* can't save */
+               g_set_error (error,
+                            GDK_PIXBUF_ERROR,
+                            GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION,
+                            _("This build of gdk-pixbuf does not support saving the image format: %s"),
+                            type);
+               ret = FALSE;
+       }
+
+       _gdk_pixbuf_unlock (image_module);
+       return ret;
 }
 
  
index 3eafd5f82ec700064ab523b7516f68db05ce8d88..e64bee7e0fede1365a28b5e0947741ae3a23325f 100644 (file)
@@ -144,7 +144,8 @@ gboolean gdk_pixbuf_set_option  (GdkPixbuf   *pixbuf,
 typedef enum /*< skip >*/
 {
   GDK_PIXBUF_FORMAT_WRITABLE = 1 << 0,
-  GDK_PIXBUF_FORMAT_SCALABLE = 1 << 1
+  GDK_PIXBUF_FORMAT_SCALABLE = 1 << 1,
+  GDK_PIXBUF_FORMAT_THREADSAFE = 1 << 2
 } GdkPixbufFormatFlags;
 
 struct _GdkPixbufFormat {
index b5c53d6035fc1b214d2b71709241fa18d3ca98cf..0ce63605d31393a5f64c49d5566fb0ae00391082 100644 (file)
@@ -50,7 +50,6 @@ static void gdk_pixbuf_loader_finalize      (GObject                *loader);
 static gpointer parent_class = NULL;
 static guint    pixbuf_loader_signals[LAST_SIGNAL] = { 0 };
 
-
 /* Internal data */
 
 #define LOADER_HEADER_SIZE 128
@@ -59,6 +58,7 @@ typedef struct
 {
         GdkPixbufAnimation *animation;
         gboolean closed;
+        gboolean holds_threadlock;
         guchar header_buf[LOADER_HEADER_SIZE];
         gint header_buf_offset;
         GdkPixbufModule *image_module;
@@ -225,8 +225,12 @@ gdk_pixbuf_loader_finalize (GObject *object)
         loader = GDK_PIXBUF_LOADER (object);
         priv = loader->priv;
 
-        if (!priv->closed)
+        if (!priv->closed) {
                 g_warning ("GdkPixbufLoader finalized without calling gdk_pixbuf_loader_close() - this is not allowed. You must explicitly end the data stream to the loader before dropping the last reference.");
+                if (priv->holds_threadlock) {
+                        _gdk_pixbuf_unlock (priv->image_module);
+                }
+        }
         if (priv->animation)
                 g_object_unref (priv->animation);
   
@@ -382,6 +386,11 @@ gdk_pixbuf_loader_load_module (GdkPixbufLoader *loader,
                         return 0;
                 }
 
+       if (!priv->holds_threadlock) {
+                _gdk_pixbuf_lock (priv->image_module);
+                priv->holds_threadlock = TRUE;
+        }
+
         priv->context = priv->image_module->begin_load (gdk_pixbuf_loader_size_func,
                                                         gdk_pixbuf_loader_prepare,
                                                         gdk_pixbuf_loader_update,
@@ -736,6 +745,11 @@ gdk_pixbuf_loader_close (GdkPixbufLoader *loader,
                 }
   
         priv->closed = TRUE;
+       if (priv->image_module) {
+                g_assert (priv->holds_threadlock);
+                _gdk_pixbuf_unlock (priv->image_module);
+                priv->holds_threadlock = FALSE;
+        }
 
         if (priv->needs_scale) 
                 {
index e81478f991f1d77b7d2216916eb48cc2af287fd0..59053a99d1a928a59dd317ee573aa8fd27dd2537 100644 (file)
@@ -79,6 +79,9 @@ struct _GdkPixbufClass {
 
 #ifdef GDK_PIXBUF_ENABLE_BACKEND
 
+void _gdk_pixbuf_lock (GdkPixbufModule *image_module);
+void _gdk_pixbuf_unlock (GdkPixbufModule *image_module);
+
 GdkPixbufModule *_gdk_pixbuf_get_module (guchar *buffer, guint size,
                                          const gchar *filename,
                                          GError **error);
index 5e7b6beb91b0f6ca0eb2c09908631b9fe8156349..5568ad65d445a706c68d91d5ee66f580bab98dc5 100644 (file)
@@ -676,7 +676,7 @@ MODULE_ENTRY (ani, fill_info) (GdkPixbufFormat *info)
        info->description = N_("The ANI image format");
        info->mime_types = mime_types;
        info->extensions = extensions;
-       info->flags = 0;
+       info->flags = GDK_PIXBUF_FORMAT_THREADSAFE;
        info->license = "LGPL";
 }
 
index 015eca8dac994d5d2e6882d28d144de0220b9139..14b7caa93e4ec06f62654b864650230027460c68 100644 (file)
@@ -1132,7 +1132,7 @@ MODULE_ENTRY (bmp, fill_info) (GdkPixbufFormat *info)
        info->description = N_("The BMP image format");
        info->mime_types = mime_types;
        info->extensions = extensions;
-       info->flags = 0;
+       info->flags = GDK_PIXBUF_FORMAT_THREADSAFE;
        info->license = "LGPL";
 }
 
index 1320922e7fb289652673c5db863c2e91c4d14715..fd78e586aa70169ef64fbdd9e49d6c632f5f5890 100644 (file)
@@ -1643,6 +1643,6 @@ MODULE_ENTRY (gif, fill_info) (GdkPixbufFormat *info)
        info->description = N_("The GIF image format");
        info->mime_types = mime_types;
        info->extensions = extensions;
-       info->flags = 0;
+       info->flags = GDK_PIXBUF_FORMAT_THREADSAFE;
        info->license = "LGPL";
 }
index 86612dd711cab8b5ac1cacc441e3435c1a3d5e61..022c93a3c738395d47bdd6a7fc3e3e3f3989b77c 100644 (file)
@@ -1210,7 +1210,7 @@ MODULE_ENTRY (ico, fill_info) (GdkPixbufFormat *info)
        info->description = N_("The ICO image format");
        info->mime_types = mime_types;
        info->extensions = extensions;
-       info->flags = GDK_PIXBUF_FORMAT_WRITABLE;
+       info->flags = GDK_PIXBUF_FORMAT_WRITABLE | GDK_PIXBUF_FORMAT_THREADSAFE;
        info->license = "LGPL";
 }
 
index 1bf4bede113282d42b155b0d9fe0adef08185613..7f21594760cf2d2b74b52af9df2d964213d266c9 100644 (file)
@@ -1071,6 +1071,6 @@ MODULE_ENTRY (jpeg, fill_info) (GdkPixbufFormat *info)
        info->description = N_("The JPEG image format");
        info->mime_types = mime_types;
        info->extensions = extensions;
-       info->flags = GDK_PIXBUF_FORMAT_WRITABLE;
+       info->flags = GDK_PIXBUF_FORMAT_WRITABLE | GDK_PIXBUF_FORMAT_THREADSAFE;
        info->license = "LGPL";
 }
index 0b1f9b1596f24d0c281a90e4a132dbf5da0816dd..d1042cb7dce0b786245b0650f819e4114a63ec4b 100644 (file)
@@ -758,6 +758,6 @@ MODULE_ENTRY (pcx, fill_info) (GdkPixbufFormat *info)
        info->description = N_("The PCX image format");
        info->mime_types = mime_types;
        info->extensions = extensions;
-       info->flags = 0;
+       info->flags = GDK_PIXBUF_FORMAT_THREADSAFE;
        info->license = "LGPL";
 }
index 3d4501fa22a5b248de689fe9699f7e88a4030ff8..7e9fb36de139f491f5e0fd19f174ef982c11a92e 100644 (file)
@@ -994,6 +994,6 @@ MODULE_ENTRY (png, fill_info) (GdkPixbufFormat *info)
        info->description = N_("The PNG image format");
        info->mime_types = mime_types;
        info->extensions = extensions;
-       info->flags = GDK_PIXBUF_FORMAT_WRITABLE;
+       info->flags = GDK_PIXBUF_FORMAT_WRITABLE | GDK_PIXBUF_FORMAT_THREADSAFE;
        info->license = "LGPL";
 }
index 7d94014501cca62a3dab91f48ef9531239dd5a36..4d2fb1ff3c1daba827bde89416d71e40a5d498a0 100644 (file)
@@ -1082,6 +1082,6 @@ MODULE_ENTRY (pnm, fill_info) (GdkPixbufFormat *info)
        info->description = N_("The PNM/PBM/PGM/PPM image format family");
        info->mime_types = mime_types;
        info->extensions = extensions;
-       info->flags = 0;
+       info->flags = GDK_PIXBUF_FORMAT_THREADSAFE;
        info->license = "LGPL";
 }
index 9fe936161ec3460f4860687af0b48e3aba5ccefd..6c20654c22fc752494d1f78de2da6eeab34657c8 100644 (file)
@@ -543,7 +543,7 @@ MODULE_ENTRY (ras, fill_info) (GdkPixbufFormat *info)
        info->description = N_("The Sun raster image format");
        info->mime_types = mime_types;
        info->extensions = extensions;
-       info->flags = 0;
+       info->flags = GDK_PIXBUF_FORMAT_THREADSAFE;
        info->license = "LGPL";
 }
 
index f4102bdf20ed1b9a7cce544567029c38267f8aef..2dc753822ee75fda88118f9c11f938d6f6b7f5ce 100644 (file)
@@ -995,6 +995,6 @@ MODULE_ENTRY (tga, fill_info) (GdkPixbufFormat *info)
        info->description = N_("The Targa image format");
        info->mime_types = mime_types;
        info->extensions = extensions;
-       info->flags = 0;
+       info->flags = GDK_PIXBUF_FORMAT_THREADSAFE;
        info->license = "LGPL";
 }
index 9beb045b015d59b1d737af38c1878369155a2d0a..c58d9cb492694935a51e4a809b35722b043d2972 100644 (file)
@@ -62,10 +62,6 @@ struct _TiffContext
 
 \f
 
-/* There's no user data for the error handlers, so we just have to
- * put a big-ass lock on the whole TIFF loader
- */
-G_LOCK_DEFINE_STATIC (tiff_loader);
 static char *global_error = NULL;
 static TIFFErrorHandler orig_error_handler = NULL;
 static TIFFErrorHandler orig_warning_handler = NULL;
@@ -242,10 +238,8 @@ tiff_image_parse (TIFF *tiff, TiffContext *context, GError **error)
                 return NULL;
         }
 
-        G_UNLOCK (tiff_loader);
        if (context)
                (* context->prepare_func) (pixbuf, NULL, context->user_data);
-        G_LOCK (tiff_loader);
 
 #if TIFFLIB_VERSION >= 20031226
         if (tifflibversion(&major, &minor, &revision) && major == 3 &&
@@ -330,10 +324,8 @@ tiff_image_parse (TIFF *tiff, TiffContext *context, GError **error)
                 _TIFFfree (rast);
              }
 
-        G_UNLOCK (tiff_loader);
        if (context)
                (* context->update_func) (pixbuf, 0, 0, width, height, context->user_data);
-        G_LOCK (tiff_loader);
         
         return pixbuf;
 }
@@ -351,8 +343,6 @@ gdk_pixbuf__tiff_image_load (FILE *f, GError **error)
         
         g_return_val_if_fail (f != NULL, NULL);
 
-        G_LOCK (tiff_loader);
-
         tiff_push_handlers ();
         
         fd = fileno (f);
@@ -371,7 +361,6 @@ gdk_pixbuf__tiff_image_load (FILE *f, GError **error)
                                 _("Failed to open TIFF image"));
                 tiff_pop_handlers ();
 
-                G_UNLOCK (tiff_loader);
                 return NULL;
         }
 
@@ -386,8 +375,6 @@ gdk_pixbuf__tiff_image_load (FILE *f, GError **error)
         
         tiff_pop_handlers ();
 
-        G_UNLOCK (tiff_loader);
-        
         return pixbuf;
 }
 
@@ -504,8 +491,6 @@ gdk_pixbuf__tiff_image_stop_load (gpointer data,
         
         g_return_val_if_fail (data != NULL, FALSE);
 
-        G_LOCK (tiff_loader);
-        
         tiff_push_handlers ();
         
         tiff = TIFFClientOpen ("libtiff-pixbuf", "r", data, 
@@ -546,8 +531,6 @@ gdk_pixbuf__tiff_image_stop_load (gpointer data,
 
         tiff_pop_handlers ();
 
-        G_UNLOCK (tiff_loader);
-
         return retval;
 }
 
@@ -627,6 +610,7 @@ MODULE_ENTRY (tiff, fill_info) (GdkPixbufFormat *info)
        info->description = N_("The TIFF image format");
        info->mime_types = mime_types;
        info->extensions = extensions;
+        /* not threadsafe, due the the error handler handling */
        info->flags = 0;
        info->license = "LGPL";
 }
index 098c8c805d2e84741ad4b1809ddc758aa193f7d1..24779b97e22d459df456d04e61a3066a7d708355 100644 (file)
@@ -368,6 +368,6 @@ MODULE_ENTRY (wbmp, fill_info) (GdkPixbufFormat *info)
        info->description = N_("The WBMP image format");
        info->mime_types = mime_types;
        info->extensions = extensions;
-       info->flags = 0;
+       info->flags = GDK_PIXBUF_FORMAT_THREADSAFE;
        info->license = "LGPL";
 }
index 45d4be79edf49136a18461eb67443a4315eb075b..6c9244cf66d648f10978e6461cb26b5433ac51ef 100644 (file)
@@ -476,6 +476,6 @@ MODULE_ENTRY (xbm, fill_info) (GdkPixbufFormat *info)
        info->description = N_("The XBM image format");
        info->mime_types = mime_types;
        info->extensions = extensions;
-       info->flags = 0;
+       info->flags = GDK_PIXBUF_FORMAT_THREADSAFE;
        info->license = "LGPL";
 }
index 67b1b011e7412778e145704d1d82b158f0491aac..f8267d5b717acd1b23c1a786fa20b25911d6d740 100644 (file)
@@ -1559,6 +1559,6 @@ MODULE_ENTRY (xpm, fill_info) (GdkPixbufFormat *info)
        info->description = N_("The XPM image format");
        info->mime_types = mime_types;
        info->extensions = extensions;
-       info->flags = 0;
+       info->flags = GDK_PIXBUF_FORMAT_THREADSAFE;
        info->license = "LGPL";
 }